package com.suiwei.advanced.exception;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.junit.jupiter.api.Test;

/**
 *@author suiwei
 *@date 2024/7/15 11:19
 */
public class ExceptionDemo {
    //编译时异常：主要起到提醒作用，需要在运行之前解决（try catch 或者throws）
    //又叫做编译时检查异常，这意味着在编译Java代码时，如果某个方法可能抛出，则该方法必须catch或者throws，否则会报错
    //catch或者throws之后，虽然编译期间不报错了，但是运行期间依然可能报错
    @Test
    void test()throws ParseException{
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        //编译时不会报错，运行时会报错；编译时异常只是说编译时检查而已，并不是编译时就判断是否报错
        Date date = sdf.parse("abcd");
        System.out.println(date);
    }

    //运行时异常：编译阶段不报错，运行时可能出现错误
    @Test
    void test1(){
        int[] arr ={1,2};
        System.out.println(arr[5]);
    }

//===================================异常的处理方式===============================================

    //0.异常默认处理方式：向上抛出
    //java中每个异常都对应一个对象，当出现异常后，虚拟机会在出现异常的代码那里自动创建一个异常对象，并向上抛出一个异常对象给调用者
    //调用者继续向上抛，直到抛给jvm虚拟机，虚拟机抛到控制台，并且终止程序
    @Test
    void test2() {
        System.out.println("开始");
        System.out.println(10/0);
        System.out.println("结束");//这一行不会执行
    }

    //1.异常处理方式1：try catch
    //好处：异常对象可以被捕获；程序不会终止，后续代码可以继续执行
    @Test
    void test3() {
        int[] arr = new int[]{};
        System.out.println("开始");
        try{
            System.out.println(arr[0]);
            System.out.println(10/0);
        }catch (ArithmeticException e){//如果try内部发生的异常，没有被catch捕获，那么这个异常就会默认往上抛
            System.out.println("捕获了计算异常："+e);
        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println("捕获了数组越界异常："+e);
        } catch (Exception e) {//可以捕获所有异常
            System.out.println("捕获了异常："+e);
        }finally{
            //即使catch里面有return，finally也会在return之前执行
        }
        System.out.println("结束");
    }

    //2.异常处理方式2：throws
    //起到声明的作用：提示这个方法可能会抛出异常
    @Test
    void test4()throws ParseException{
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        Date date = sdf.parse("abcd");
        System.out.println(date);
    }

    //==============================可以自己定义异常，往外抛出======================
    
    @Test
    void test5(){
        try {
            method3(200);
        }catch (Exception e){
            //Throwable常用方法：1.getMessage()；2.printStackTrace()

            //e.getMessage()只输出错误原因，不输出路径
            System.out.println(e.getMessage());
            //只输出异常的简单信息，不输出路径；
            System.out.println(e);
            //输出异常的路径信息，是完整的异常错误信息
            e.printStackTrace();

        }

    }
    //抛出编译时异常
    void method1(int age)throws Exception{
        if (age<0||age>120){
            //编译时异常，必须throws抛出
            throw new Exception("年龄输入有误");
        }else {
            System.out.println("你输入的年龄为："+age);
        }
    }
    //抛出运行时异常
    void method2(int age) {
        if (age<0||age>120){
            //运行时异常（也称为未检查异常Unchecked Exception）不需要显式地使用throw关键字抛出
            //也不需要在方法签名中通过throws关键字声明
            //运行时异常一般表示程序设计有问题，需要更改
            throw new RuntimeException("年龄输入有误");
        }else {
            System.out.println("你输入的年龄为："+age);
        }
    }
    //抛出自定义的运行时异常
    void method3(int age) {
        if (age<0||age>120){
            throw new CustomException("自定义运行时异常");
        }else {
            System.out.println("你输入的年龄为："+age);
        }
    }



}
